package com.yangye.niodemo.rpc.server;

import com.yangye.niodemo.rpc.protocol.PackageMsg;
import com.yangye.niodemo.rpc.protocol.RpcBody;
import com.yangye.niodemo.rpc.protocol.RpcHeader;
import com.yangye.niodemo.rpc.util.SerDerUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;

/**
 * @author yangye
 * @date 2020/12/29
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		PackageMsg packageMsg = (PackageMsg) msg;

		ctx.executor().execute(() -> {
			try {
				String name = packageMsg.getBody().getName();
				String methodName = packageMsg.getBody().getMethodName();
				Object o = Dispatcher.get(name);
				Class<?> clazz = o.getClass();
				Object res = null;

				Method method = null;
				method = clazz.getMethod(methodName, packageMsg.getBody().getParameterTypes());
				res = method.invoke(o, packageMsg.getBody().getArgs());

				RpcBody respBody = new RpcBody();
				respBody.setResult(res.toString());
				byte[] bodyBytes = SerDerUtil.ser(respBody);

				RpcHeader respHeader = new RpcHeader();
				respHeader.setRequestId(packageMsg.getHeader().getRequestId());
				respHeader.setBodyLen((long) bodyBytes.length);
				byte[] headerBytes = SerDerUtil.ser(respHeader);

				// 返回结果
				ByteBuf byteBuf = PooledByteBufAllocator.DEFAULT.directBuffer(headerBytes.length + bodyBytes.length);
				byteBuf.writeBytes(headerBytes);
				byteBuf.writeBytes(bodyBytes);
				ctx.writeAndFlush(byteBuf);
			} catch (Exception e) {
				e.printStackTrace();
			}
		});
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		System.out.println("client close");
	}
}
